
package com.sawgdev.android.bokuiki.common.mail;

import com.sawgdev.android.bokuiki.bean.BeanMailSetting;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.widget.Toast;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
 * <pre>
 * メール送信の共通クラスです。
 * </pre>
 *
 * @author Bambooroid
 */
public class Mail {

    private Context context;

    /** メール設定情報を保存するファイル名 */
    private static final String DB_NAME = "mail_db";

    /**
     * <pre>
     * コンストラクタです。
     * 利用するActivityのcontextを引数で渡します。
     * </pre>
     *
     * @param context
     */
    public Mail(Context context) {
        this.context = context;
    }

    /**
     * <pre>
     * メールを送信するメソッドです。
     * </pre>
     *
     * @param to 送信先メールアドレス
     * @param subject メールタイトル
     * @param text メール本文
     */
    public void sendMail(String to, String subject, String text) {
        BeanMailSetting beanMailSetting = getMailData();
        Properties properties = new Properties();
        properties.put("mail.smtp.host", beanMailSetting.getSmtpName());
        properties.put("mail.host", beanMailSetting.getHostName());
        properties.put("mail.smtp.port", beanMailSetting.getPortNo());
        properties.put("mail.smtp.starttls.enable", beanMailSetting.getTls());
        properties.put("mail.smtp.auth", beanMailSetting.getSmtpAuth());

        Session session = Session.getDefaultInstance(properties);
        session.setDebug(true);

        MimeMessage msg = new MimeMessage(session);
        try {
            msg.setSubject(subject, "utf-8");
            msg.setFrom(new InternetAddress(beanMailSetting.getMailAddress()));
            msg.setSender(new InternetAddress(beanMailSetting.getMailAddress()));
            msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
            msg.setText(text, "utf-8");

            Transport t = session.getTransport("smtp");
            t.connect(beanMailSetting.getMailAddress(), beanMailSetting.getMailPassword());
            t.sendMessage(msg, msg.getAllRecipients());
        } catch (MessagingException e) {
            e.printStackTrace();
            Toast.makeText(context, "メールの設定情報が不正な為、メールを送信できませんでした。", Toast.LENGTH_LONG).show();
        }
    }

    /**
     * <pre>
     * メールの設定情報を取得します。
     * </pre>
     *
     * @return メール設定情報
     */
    private BeanMailSetting getMailData() {
        SharedPreferences sp = context.getSharedPreferences(DB_NAME, Context.MODE_PRIVATE);
        BeanMailSetting beanMailSetting = new BeanMailSetting();
        beanMailSetting.setMailType(sp.getInt("MailType", 1));
        if (beanMailSetting.getMailType() == 1) {
            beanMailSetting.setMailAddress(getGmailAddress(context));
            Encipherment encipherment = new Encipherment();
            try {
                beanMailSetting.setMailPassword(encipherment.decrypt(sp.getString("MailPassword",
                        "")));
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            }
            beanMailSetting.setSmtpName(GmailConstants.SMTP_NAME);
            beanMailSetting.setHostName(GmailConstants.HOST_NAME);
            beanMailSetting.setPortNo(GmailConstants.PORT_NO);
            beanMailSetting.setSmtpAuth(GmailConstants.SMTP_AUTH);
            beanMailSetting.setTls(GmailConstants.TLS);
        } else {
            beanMailSetting.setMailAddress(sp.getString("MailAddress", ""));
            Encipherment encipherment = new Encipherment();
            try {
                beanMailSetting.setMailPassword(encipherment.decrypt(sp.getString("MailPassword",
                        "")));
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            }
            beanMailSetting.setSmtpName(sp.getString("SmtpName", ""));
            beanMailSetting.setHostName(sp.getString("HostName", ""));
            beanMailSetting.setPortNo(sp.getString("PortNo", ""));
            beanMailSetting.setSmtpAuth(sp.getString("SmtpAuth", "true"));
            beanMailSetting.setTls(sp.getString("Tls", "true"));
        }
        return beanMailSetting;
    }

    /**
     * <pre>
     * 端末に設定されたGmailのアドレスを取得します。
     * </pre>
     *
     * @param context
     * @return Gmailアドレス
     */
    public static String getGmailAddress(Context context) {
        AccountManager accountManager = AccountManager.get(context);
        Account[] accounts = accountManager.getAccountsByType("com.google");
        String gmailAddress = "";
        for (Account account : accounts) {
            gmailAddress = account.name;
            break;
        }
        return gmailAddress;
    }
}
